home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
keyb
/
autokey.zip
/
AUTOKEY.ASM
next >
Wrap
Assembly Source File
|
1989-01-24
|
14KB
|
554 lines
comment |
This program reads a file of keystrokes into a buffer and uses them
to replace keyboard input until the buffer is empty.
Written for MASM 5.1 (should compile with earlier versions)
Save as AUTOKEY.ASM
Compile: MASM AUTOKEY;
LINK AUTOKEY; (ignore stack segment warning)
EXE2BIN AUTOKEY.EXE AUTOKEY.COM
|
CR equ 0dh ;Definitions for
LF equ 0ah ; the program's use
TAB equ 09h
code_seg segment
assume cs:code_seg, ds:code_seg, es:code_seg
org 100h ;.COM file format
start: jmp begin
;---------
; Data used by the
; memory-resident portion of
; the program.
;---------
kbd_head equ 1ah
kbd_tail equ 1ch
kbd_start equ 80h
kbd_end equ 82h
int8_gate db ?
old_08 dd ?
old_09 dd ?
save_ss dw ?
save_sp dw ?
dw 50h dup (?)
our_stack equ $-2
buf_ptr dw offset keybuf
buf_count dw 0
BUF_SIZE equ 500 ;Change to suit your needs
keybuf db BUF_SIZE dup (?)
;---------
; Keyboard Interrupt 09 hex
; While keys are being sent
; to the buffer from Autokey,
; disable the physical keyboard
; by simply ignoring all keystrokes
;---------
new_int09 proc far
test cs:buf_count,-1 ;Are we sending keystrokes?
jz orig_int9 ;No -- go
push ax ;Else save AX
in al,60h ;Read the keystroke
in al,61h ;Get Port B value
or al,80h ;Set high bit
out 61h,al ;Send it out
and al,7fh ;Clear high bit
out 61h,al ;We said we received it
mov al,20h ;Signal end of
out 20h,al ; hardware interrupt
pop ax ;Recover original AX
iret ;Key is swallowed
orig_int9:
jmp dword ptr cs:[old_09] ;Use original code for Int 9
new_int09 endp
;---------
; Timer Interrupt
; This is where we stuff the
; keyboard buffer
;---------
new_int08 proc far
pushf ;Simulate an interrupt call
call dword ptr cs:[old_08] ;Hand off to previous code
test cs:buf_count,-1 ;Anything to stuff
jz new8_out ;No -- leave immediately
test cs:int8_gate,-1 ;Okay to execute?
jz stuff_keys
new8_out:
iret ;Return to interrupted program
stuff_keys:
;------
; Set the gate flag.
; switch stacks, and save
; necessary registers.
;------
mov cs:int8_gate,-1 ;Don't allow recursive calls
push ax ;Save caller's AX
mov cs:[save_ss],ss ;Save caller's stack
mov cs:[save_sp],sp
cli ;Interrupts off to switch stack
mov ax,cs ;Get our segment
mov ss,ax ; in SS
mov sp,offset our_stack ;Move to our stack
and sp,0fffeh ;Make sure it's even
sti ;Interrupts on now
push ds ;Save caller's segments
push es
mov ds,ax ;Point to our segment
push di ;Now save registers we need
push si
push bx
mov ax,40h ;Segment for BIOS buffer
mov es,ax ;ES ==> BIOS segment
mov di,es:[kbd_head] ;Get head of buffer
mov bx,es:[kbd_tail] ; and the tail
cmp di,bx ;Is buffer empty?
jne end_stuff ;No -- forget it
mov si,[buf_ptr] ;DS:SI ==> head of our buffer
lodsw ;Get next word
mov [buf_ptr],si ;Save new pointer
dec [buf_count] ;Count this keystroke
or ax,ax ;Is keystroke null?
jz end_stuff ;Yes -- don't stuff it
stosw ;Else put it in buffer
inc bx ;Move tail pointer
inc bx
cmp bx,es:[kbd_end] ;Past the end?
jl dont_wrap ;No -- go
mov bx,es:[kbd_start] ;Get start of key buffer
dont_wrap:
mov es:[kbd_tail],bx ;Save new value
end_stuff:
pop bx ;Clear our stack
pop si
pop di
pop es
pop ds
cli ;Interrupts off to
mov ss,cs:[save_ss] ; switch stacks
mov sp,cs:[save_sp]
pop ax ;All done
mov cs:int8_gate,0 ;Let next call in
jmp new8_out ;And leave
new_int08 endp
res_code equ $ - new_int08
res_size equ $-start
;---------
; Installation code
; and file parsing.
; Everything from here to the end
; is discarded when the TSR is installed
;---------
;---------
; Transient Data
;---------
temp_buf db BUF_SIZE * 2 dup (0)
hello db CR,"AUTOKEY Automatic Keyboard Entry",CR,LF,"$"
bad_ver db "This program requires DOS 2.0 or later",CR,LF,"$"
no_file db "Usage: AUTOKEY keyfile",CR,LF,"$"
no_open db "Cannot open keystroke file",CR,LF,"$"
bad_read db "Error reading keystroke file",CR,LF,"$"
too_large db "Keystroke file is too large",CR,LF,"$"
installed db "Program and keystrokes installed in memory",CR,LF,"$"
reloaded db "Keystroke buffer reloaded",CR,LF,"$"
first_byte db ? ;For 1st of 2-byte code
code_table dw "cA",1e01h ;Control keys
dw "cB",3002h
dw "cC",2e03h
dw "cD",2004h
dw "cE",1205h
dw "cF",2106h
dw "cG",2207h
dw "cH",2308h
dw "cI",1709h
dw "cJ",240ah
dw "cK",250bh
dw "cL",260ch
dw "cM",320dh
dw "cN",310eh
dw "cO",180fh
dw "cP",1910h
dw "cQ",1011h
dw "cR",1312h
dw "cS",1f13h
dw "cT",1414h
dw "cU",1615h
dw "cV",2f16h
dw "cW",1117h
dw "cX",2d18h
dw "cY",1519h
dw "cZ",2c1ah
dw "aA",1e00h ;Alt keys
dw "aB",3000h
dw "aC",2e00h
dw "aD",2000h
dw "aE",1200h
dw "aF",2100h
dw "aG",2200h
dw "aH",2300h
dw "aI",1700h
dw "aJ",2400h
dw "aK",2500h
dw "aL",2600h
dw "aM",3200h
dw "aN",3100h
dw "aO",1800h
dw "aP",1900h
dw "aQ",1000h
dw "aR",1300h
dw "aS",1f00h
dw "aT",1400h
dw "aU",1600h
dw "aV",2f00h
dw "aW",1100h
dw "aX",2d00h
dw "aY",1500h
dw "aZ",2c00h
dw "F1",3b00h ;Function keys
dw "F2",3c00h
dw "F3",3d00h
dw "F4",3e00h
dw "F5",3f00h
dw "F6",4000h
dw "F7",4100h
dw "F8",4200h
dw "F9",4300h
dw "Ft",4400h
dw "Fe",8500h
dw "Fv",8600h
dw "s1",5400h ;Shift Function keys
dw "s2",5500h
dw "s3",5600h
dw "s4",5700h
dw "s5",5800h
dw "s6",5900h
dw "s7",5a00h
dw "s8",5b00h
dw "s9",5c00h
dw "st",5d00h
dw "se",8700h
dw "sv",8800h
dw "c1",5e00h ;Control Function keys
dw "c2",5f00h
dw "c3",6000h
dw "c4",6100h
dw "c5",6200h
dw "c6",6300h
dw "c7",6400h
dw "c8",6500h
dw "c9",6600h
dw "ct",6700h
dw "ce",8900h
dw "cv",8a00h
dw "a1",6800h ;Alt function keys
dw "a2",6900h
dw "a3",6a00h
dw "a4",6b00h
dw "a5",6c00h
dw "a6",6d00h
dw "a7",6e00h
dw "a8",6f00h
dw "a9",7000h
dw "at",7100h
dw "ae",8b00h
dw "av",8c00h
dw "a!",7800h ;Alt-numbers
dw "a@",7900h
dw "a#",7a00h
dw "a$",7b00h
dw "a%",7c00h
dw "a^",7d00h
dw "a&",7e00h
dw "a*",7f00h
dw "a(",8000h
dw "a)",8100h
dw "t1",9800h ;Tandy 1000 F11 & F12
dw "t2",9900h
dw "!1",0a200h ; (shifted)
dw "!2",0a300h
dw "^1",0ac00h ; (control)
dw "^2",0ad00h
dw "~1",0b600h ; (alt)
dw "~2",0b700h
dw "HM",4700h ;Home
dw "UA",4800h ;Up-arrow
dw "PU",4900h ;Page Up
dw "LA",4b00h ;Left Arrow
dw "RA",4d00h ;Right Arrow
dw "EN",4f00h ;End
dw "DA",5000h ;Down Arrow
dw "PD",5100h ;Page down
dw "IN",5200h ;Insert
dw "DL",5300h ;Delete
dw "CR",1c0dh ;Return/Enter
dw "Tb",0f09h ;Tab
dw "BK",0e08h ;Backspace
dw "sb",0f00h ;Shift-Tab
dw "ES",011bh ;Escape
dw "P+",4e2bh ;Pad Plus
dw "P-",4a2dh ;Pad Minus
dw "ch",7700h ;Ctrl-home
dw "cu",8400h ;Ctrl-up
dw "cl",7300h ;Ctrl-left
dw "cr",7400h ;Ctrl-right
dw "ce",7500h ;Ctrl-end
dw "cd",7600h ;Ctrl-down
dw "NL",0000h ;Null
code_len equ $-code_table ;Length of the table
begin: lea dx,hello ;DS:DX ==> opening message
mov ah,9 ;Print the message
int 21h
mov ah,30h ;Get DOS version
int 21h
cmp al,2 ;At least version 2?
jae version_ok ;Yes -- go
lea dx,bad_ver ;Else report error & leave
jmp error
version_ok:
mov ax,3508h ;Get location of Int 08h
int 21h
mov word ptr [old_08],bx ;Save the address
mov word ptr [old_08+2],es ; in ES:BX
mov ax,3509h ;Get location of Int 09h
int 21h
mov word ptr [old_09],bx ;Save the address
mov word ptr [old_09+2],es ; in ES:BX
lea di,new_int09 ;Get code start address in DI
mov si,di ;Copy to SI
mov cx,res_code ;Bytes to compare
repz cmpsb ;Are we already installed?
jz read_file ;Yes -- go
push ds ;Else move ES
pop es ; to this segme